package br.edu.ufcg.fpc.locks;

/**
 * Bakery lock.
 * 
 * @author Demontie Junior
 * @author Leandro Brito
 *
 */
public class BakeryLock implements BakeryLockIF {

	volatile boolean[] escolhendo;
	volatile int[] num;

	public BakeryLock(int n) {
		escolhendo = new boolean[n];
		num = new int[n];
		for (int i = 0; i < n; i++) {
			escolhendo[i] = false;
			num[i] = 0;
		}
	}

	@Override
	public void lock(int id) {
		// Porta de acesso...
		escolhendo[id] = true;
		for (int j = 0; j < num.length; j++) //MAX
			if (num[j] > num[id])
				num[id] = num[j];
		num[id]++;
		escolhendo[id] = false;
		
		// Busy Wait
		for (int j = 0; j < num.length; j++) {
			while (escolhendo[j]);
			while ((num[j] != 0) && 
					((num[j] < num[id]) || 
					  ((num[j] == num[id]) && j < id)));
		}
	}

	@Override
	public void unlock(int id) {
		num[id] = 0;	
	}

}
